/**
	Copyright (c) 2011 ATTi 
	All rights reserved.
	Author: Michael Shu
	Date: 11/15/2011
*/

global without sharing class CaseIOGInitiateChange {
	WebService static String CreateFulfillmentItems(string id){
		Case cs = [select Id, CaseNumber, OwnerId, IR_Priority__c, CSS_CustomerID__c, Fulfillment_Product_Group_Name__c, UDAC_Code__c, Region__c, AccountId, ContactId
		                  , Product_Issue__c, Item_Id__c, Feature_Code__c, Feature_ID__c, Price_Plan_ID__c, UDAC_Description__c, FI_Region_Code__c
		                  , Account.OwnerId, Account.Owner.ManagerId, Account.RecordType.DeveloperName, Change_Detail__c, Change_Level__c, Product_code__c
		                  , (select CommentBody from CaseComments)
		           from Case where ID =: id];
		if(cs == null){
			return ' ERROR : Initiate Change Fail! \n Case Id doesn\'t exist!';
		}
		Fullfilment_Item__c fi;
		String info = '';
		Savepoint sp = Database.setSavepoint();
		if(cs.UDAC_Code__c == null || cs.UDAC_Code__c == 'other'){
			info = 'donotlink';
		}else{
			List<Fullfilment_Item__c> extFIs = [select Id, Escalated__c 
												from Fullfilment_Item__c
												where Status__c NOT IN: CaseIOGClass.FI_END_STATUS
												    and Transaction_Type__c != 'Renewal' and Transaction_Type__c != 'Cancellation'
												    and Region__c =: cs.Region__c
													and	((Region__c like '%In%'  
												       		and Customer_ID__c =: cs.CSS_CustomerID__c and Product_Code__c  =: cs.Product_code__c  and Product_Issue__c =: cs.Product_Issue__c  
												       		and Item_Id__c     =: ''+cs.Item_Id__c     and Price_Plan_Id__c =: cs.Price_Plan_Id__c and Feature_Id__c    =: cs.Feature_Id__c)
												   		  or (Region__c like '%Out%' and Price_Plan_Id__c  =: cs.Price_Plan_Id__c and Price_Plan_Id__c != null)
												    	)];
			if(!extFIs.isEmpty()){
				info = 'exist';
				cs.Fulfillment_Item__c = extFIs[0].Id;
				if(cs.IR_Priority__c == 'Standard'){
					if(extFIs[0].Escalated__c){
						cs.IR_Priority__c = 'Escalation';
					}
				}else{
					if(!extFIs[0].Escalated__c){
						extFIs[0].Escalated__c = true;
						extFIs[0].Escalation_Reason__c = 'Initial Escalation';
						extFIs[0].Escalation_Notes__c = 'Escalated by Case';
						info = 'exist_no_escalate';
						try{
							//update extFIs[0];
						}catch(Exception ex){
							info = ' Error when updating the existing FI to Escalated. No Changes was saved \n ' + ex.getMessage();
							GeneralConstants.mailAnyExceptionToMe('CaseIOGInitiateChange', ' updating the existing FI fail ', ex);
						}
					}
				}
				try{
					createFINotes(cs, cs.Fulfillment_Item__c);
				}catch(Exception ex){
					info = ' Error when inserting a new Notes to existing FI. No Changes was saved \n ' + ex.getMessage();
					GeneralConstants.mailAnyExceptionToMe('CaseIOGInitiateChange', ' inserting notes to an existing FI fail ', ex);
				}				
			}else{									   
				List<Fulfillment_Products__c> fulfillProduct = [select Fulfillment_Product_Group__c 
				                                                from Fulfillment_Products__c 
				                                                where Status__c = 'Active' and Product_UDAC_Code__c =: cs.UDAC_Code__c 
				                                                         and Fulfillment_Product_Group__r.Name =: cs.Fulfillment_Product_Group_Name__c];
				if(!fulfillProduct.isEmpty()){
					ID FulfillmentProductGroupId = fulfillProduct[0].Fulfillment_Product_Group__c;
					List<Workflow_Fulfillment_Group__c> workflow = [select Id 
																	from Workflow_Fulfillment_Group__c 
																	where Order_Types__c =: 'Change Request' and Workflow__r.Status__c = 'Active' and status__c ='Active' 
																	      and Product_Group__c =: FulfillmentProductGroupId and Advertiser_Region__c =: cs.Region__c];
					if(!workflow.isEmpty()){
						info = 'new';
						try{
							fi  = createNewFI(cs, FulfillmentProductGroupId);
							cs.Fulfillment_Item__c = fi.Id;
							createFINotes(cs, cs.Fulfillment_Item__c);
						}catch(Exception ex){
							info = ' Error when inserting a new FI. No Changes was saved \n ' + ex.getMessage();
							GeneralConstants.mailAnyExceptionToMe('CaseIOGInitiateChange', ' inserting a new FI fail ', ex);
						}
					}
				}
			}
		}
		String rst;
		if(info.toLowerCase().contains('error')){
			rst = info;
			Database.rollback(sp);
		}else{
			if(info == 'donotlink'){
				cs.Status = 'In Progress';
				rst = ' No Linked Item on Case. Stub Case Status now \'In Progress\' ';			
			}else if(info == 'new'){
				cs.Status = 'In Workflow';
				rst = ' Initiate Change Complete. A new Fulfillment Item is created ';
			}else if(info == 'exist'){
				cs.Status = 'In Workflow';
				rst = ' Existing Fulfillment Item found. Case linked to existing workflow already in progress. ';
			}else if(info == 'exist_no_escalate'){
				cs.Status = 'In Workflow';
				rst = ' Existing Fulfillment Item found. Case linked to existing workflow already in progress. Fulfillment Item HAS NOT been escalated.';
			}else{
				cs.Status = 'In Progress';
				rst = ' No iFulfill Change Workflow. Stub Case Status now \'In Progress\'. ';
			}
			try{
				update cs;
			}catch(Exception ex){
				rst = ' Error when update the Case. No Changes was saved \n ' + ex.getMessage();
				GeneralConstants.mailAnyExceptionToMe('CaseIOGInitiateChange', ' update case fail ', ex);
				Database.rollback(sp);
			}
			if(fi != null){
				callFulfillmentWebService(''+fi.Id,cs.CSS_CustomerID__c,fi.Product_code__c,fi.Product_Issue__c,fi.Item_Id__c,''+fi.Price_Plan_Id__c,''+fi.Feature_Id__c,fi.FI_Region_Code__c);
			}
		}
		return rst;
	}
	
	private static Fullfilment_Item__c createNewFI(Case c, ID fulProductGroupId){
		Fullfilment_Item__c f = new Fullfilment_Item__c(Activity_Code__c = 'CHGFCLTR');
		f.Account__c = c.AccountId;
		f.Contact__c = c.ContactId;
		f.Product_Code__c = c.Product_code__c;
		f.Product_Issue__c = c.Product_Issue__c;
		f.Item_Id__c = '' + c.Item_ID__c;
		f.UDAC__c = c.UDAC_Code__c;
		f.Feature_Code__c = c.Feature_Code__c;
		f.Feature_Id__c = c.Feature_Id__c;
		f.Price_Plan_Id__c = c.Price_Plan_Id__c;
		f.UDAC_Description__c = c.UDAC_Description__c;
		f.Feature__c = null;
		f.Fulfillment_Product_Group__c =  fulProductGroupId;
		f.FI_Region_Code__c = c.FI_Region_Code__c;
		f.Region__c = c.Region__c;
		if(c.Account.RecordType.DeveloperName == 'Local_Advertiser'){
			f.Sales_Rep__c = c.Account.OwnerId;
			f.Sales_Manager__c = c.Account.Owner.ManagerId;
		}
		if(c.IR_Priority__c == 'Standard'){
			f.Transaction_Type__c = 'Change Request';
			f.Escalated__c = false;
		}else{
			f.Transaction_Type__c = 'Escalation';
			f.Escalated__c = true;
			f.Escalation_Reason__c = 'Initial Escalation';
			f.Escalation_Notes__c = 'Escalated by Case';
		}
		f.Related_Case_Id__c = c.Id;
		f.OwnerId__c = c.OwnerId;
		f.Change_Description__c = c.Change_Detail__c;
		f.Change_Level__c = c.Change_Level__c;
		insert f;
		return f;
	}
	
	private static void createFINotes(Case pCase, ID fId){
		List<Notes__c> notes = new List<Notes__c>();
		for(CaseComment cc : pCase.CaseComments){
			Notes__c note = new Notes__c();
			note.Title__c = 'Case ' + pCase.CaseNumber;
			note.Notes__c = cc.CommentBody;
			note.Fullfilment_Notes__c = fId;
			notes.add(note);
		}
		if(!notes.isEmpty()){
			insert notes;
		}
	}
	
	@future (callout=true)
	private static void callFulfillmentWebService(String salesforceId,String customerId,String productCode,String productIssue,String itemId,String priceplanId,String featureId,String region){
		FulfillmentWebService.BasicHttpBinding_IFulFillmentService delegate = new FulfillmentWebService.BasicHttpBinding_IFulFillmentService();
		delegate.UpsertFulfillmentMapping(salesforceId,customerId,productCode,productIssue,itemId,priceplanId,featureId,region);
	}
	
	private static String mapRegionCode(String regionCode){
		String regionName;
		if(regionCode == 'B'){
			regionName = 'In-Region East';
		}else if(regionCode == 'S' || regionCode == 'W' || regionCode == 'M'){
			regionName = 'In-Region West';
		}else if(regionCode == 'I' || regionCode == 'O'){
			regionName = 'Out-Of-Region';
		}else{
			regionName = 'Unknown Code: ' + regionCode;
		}
		return regionName;
	}
}